/** 
*@class AshSelectBox
*@extends AshEventDispatcher
*@desc
<pre>
 Author			: Sehan. An
 Creation Date : 	2011.08.25
 Last Modified : 	2011.08.25

 * description |
	- 본 클래스는 표준 selectbox의 디자인 커스터마이징을 위해서 고안된 클래스이다.

	- 본클래스는 static 타입의 클래스이다. 즉, 클래스이자 자체가 이미 인스턴스이다. 따라서 그냥 바로 클래스로 바로 사용하면 된다.
	  런타임에 현재 적용된 프로젝트의 모든 select 개체를 하나의 디자인으로 일괄적용하기 위한 방법임으로 개별설정은 무시된다.
	  개별 디자인 커스터마이징은 AshSelectBoxEX 클래스를 이용토록 한다.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

* usage|
<code>

</code>
</pre>
*/

var AshSelectBox = new AshEventDispatcher();

/** it can replace the following properies with the specified custom colors in runtime.
*@static
*@return String
*@desc
	ex)
	AshSelectBox.mouseOverColor = '#d0d0d0';
	AshSelectBox.mouseOverBgColor = '#000000';
	AshSelectBox.textPadding = '5px';
	AshSelectBox.verticalAlign = 'text-bottom';
*/
AshSelectBox.mouseOverColor = '#ffffff';

/**
*@static
*@return String
*/
AshSelectBox.mouseOverBgColor = '#333333';

/**
*@static
*@return uint
*/
AshSelectBox.textPadding = 10;

/**
*@static
*@return String
*/
AshSelectBox.verticalAlign = 'middle';


/**
*@static
*@return Array
*/
AshSelectBox.dispatchEventList = [ 'change', 'mousedown', 'mouseup', 'mousemove', 'click' ];

AshSelectBox.initialize = function() 
{
	var own = this;
	this.selects = [];
	this._dEvent = null;
	this._builtInSelects = null;

	this._createCustomSelect = function(bsElement) {
		var x, y, w, h, list;
		var element = document.createElement('span'); // it must be a span not div. (div로 처리하면 ie6~7까지 block엘리먼트로 동작해서 다음엘리먼트가 줄바꿈되는현상발생)

		bsElement.style.display = 'inline'; // force shows to calculate the layout size of the builtin select, because if display prop's 'none', the rendering size will always be return 0,
		x = bsElement.offsetLeft, y = bsElement.offsetTop, w = bsElement.offsetWidth + this.textPadding, h = bsElement.offsetHeight;
		bsElement.style.display = 'none';

		element.cowork = bsElement;
		element.className = bsElement.className;
		element.style.cssText += ';display:inline-block; vertical-align:'+this.verticalAlign+'; width:'+w+'px; height:'+h+'px; cursor:default; ';
		element.innerHTML = "<span style='padding: 0px "+this.textPadding+"px; '></span>";
		element.onmousedown = function() {
			own._show(this);
		};
		
		list = element.listElement = document.createElement('div');
		list.className =  bsElement.className;
		list.style.cssText += '; position:absolute; width:'+w+'px; height:auto;  background-image: none; cursor:default; ';

		for(var l = bsElement.options.length, o, c, sc, span, i = 0; i < l; i++) {
			o = bsElement.options[i];
			c = list.appendChild(document.createElement('div'));
			c.style.cssText += '; padding: 0px '+this.textPadding+'px; height:'+h+'px; ';

			c.index = i;
			c.value = o.value;
			c.innerHTML = o.innerHTML;

			c.onmouseover = function() {
				this.style.color = own.mouseOverColor;
				this.style.backgroundColor = own.mouseOverBgColor
			}
			c.onmouseout = function() {
				this.style.color ='';
				this.style.backgroundColor ='';
			}
			c.onclick = function() {
				own._changeValue(element, this);
			}

			if(!sc) sc = c;
			if(o.selected) sc = c;
		}
		
		for(l = this.dispatchEventList.length, i = 0; i < l; i++) {
			var type = this.dispatchEventList[i];
			if(bsElement['on'+type]) {
				if(element['on'+type]) element['_on'+type] = element['on'+type];
				element['on'+type] = function() {
					var type = arguments.callee.delegateType;
					if(this['_on'+type]) this['_on'+type].call(this);
					own._dispatchEvent(this.cowork, type);
				}
				element['on'+type].delegateType = type;
			}
		}

		bsElement.parentNode.insertBefore(element, bsElement);
		own._changeValue(element, sc, false);

		return element;
	};

	this._changeValue = function(element, c, noEvent) {
		var bsElement = element.cowork;
		element.firstChild.innerHTML = c.innerHTML;
		if(bsElement.selectedIndex != c.index) {
			bsElement.options[c.index].selected = true;
			if(!noEvent) this._dispatchEvent(bsElement, 'change');
		}
		this._hide();
	};

	this._show = function(element) {
		var list = element.listElement;
		if(list.style.display == 'block') return;
		list.style.display = 'block';
		document.body.appendChild(list);

		var sinfo = AshUtil.document.scrollInfo(), d = document.documentElement, x,y, p;
		p = AshUtil.globalCoordinates(element);
		x = p.x; y = p.y; y += element.offsetHeight-1;
		
		if(y + list.offsetHeight > d.clientHeight + sinfo.top) y = y - list.offsetHeight - element.offsetHeight+2;
		AshUtil.move(list, x,y);
		
		window.setTimeout(function() {
			own._oldSelect = element;
			own._dEvent.addEventListener('mousedown', own._hide);
		},200);
	};

	this._hide = function(e) {
		if(!own._oldSelect) return;
		var list = own._oldSelect.listElement;
		if(e) if(AshUtil.contains(list, e.target || e.srcElement)) return;
		list.style.display = 'none';
		own._dEvent.removeEventListener('mousedown', own._hide);
	};

	this._dispatchEvent = function(bsElement, type) {
		if(bsElement.dispatchEvent) {
			var evt = document.createEvent("Event");
			evt.initEvent(type, true, false);
			bsElement.dispatchEvent(evt);
		}
		else {
			type = 'on'+type;
			if(bsElement[type]) bsElement[type].call(bsElement);
		}
	};

	this._initialize = function() {
		this._dEvent = new AshEventDispatcher(document);
		this._builtInSelects = document.body.getElementsByTagName('select');
		for(var l = this._builtInSelects.length, i = 0; i < l; i++) {
			if(this._builtInSelects[i].className) this.selects.push( this._createCustomSelect(this._builtInSelects[i]) );
		}
	};

	var oEvt = new AshEventDispatcher(window); oEvt.addEventListener('load', function() { own._initialize(); });
}; AshSelectBox.initialize();
